"use client";

import * as React from "react";
import { useState, useTransition, useEffect } from "react";
import { Settings, Plus, Users } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { toast } from "sonner";
import { DepartmentTreeView } from "./department-tree-view";
import { DepartmentDomainAssignmentDialog } from "./department-domain-assignment-dialog";
import { 
  type DepartmentNode 
} from "@/lib/users/knox-service";
import { 
  assignDomainToDepartments,
  getDepartmentDomainAssignments,
  type UserDomain
} from "@/lib/users/department-domain/service";
import { DOMAIN_OPTIONS } from "./domain-constants";

interface DepartmentMenuAccessManagerProps {
  departmentsPromise: Promise<DepartmentNode[]>;
  companyInfo: { code: string; name: string };
}

interface DepartmentAssignment {
  id: number;
  departmentCode: string;
  departmentName: string;
  assignedDomain: string;
  description?: string | null;
}

export function DepartmentMenuAccessManager({ 
  departmentsPromise, 
  companyInfo 
}: DepartmentMenuAccessManagerProps) {
  const [departments, setDepartments] = useState<DepartmentNode[]>([]);
  const [selectedDepartments, setSelectedDepartments] = useState<string[]>([]);
  const [assignments, setAssignments] = useState<DepartmentAssignment[]>([]);
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [isPending, startTransition] = useTransition();
  const [isDepartmentsLoading, setIsDepartmentsLoading] = useState(true);
  const [isAssignmentsLoading, setIsAssignmentsLoading] = useState(true);

  // Promise를 해결하여 부서 데이터 로드
  useEffect(() => {
    const loadDepartments = async () => {
      setIsDepartmentsLoading(true);
      try {
        const departmentTree = await departmentsPromise;
        setDepartments(departmentTree);
      } catch (error) {
        console.error("부서 트리 로드 실패:", error);
        toast.error("부서 정보를 불러오는데 실패했습니다.");
        setDepartments([]);
      } finally {
        setIsDepartmentsLoading(false);
      }
    };

    loadDepartments();
  }, [departmentsPromise]);

  // 기존 할당 정보 로드
  useEffect(() => {
    const loadAssignments = async () => {
      setIsAssignmentsLoading(true);
      try {
        const assignmentData = await getDepartmentDomainAssignments();
        setAssignments(assignmentData as DepartmentAssignment[]);
      } catch (error) {
        console.error("할당 정보 로드 실패:", error);
        toast.error("할당 정보를 불러오는데 실패했습니다.");
        setAssignments([]);
      } finally {
        setIsAssignmentsLoading(false);
      }
    };

    loadAssignments();
  }, []);

  // 선택된 부서들의 정보 가져오기
  const getSelectedDepartmentInfo = React.useCallback(() => {
    const findDepartment = (nodes: DepartmentNode[], code: string): DepartmentNode | null => {
      for (const node of nodes) {
        if (node.departmentCode === code) {
          return node;
        }
        const found = findDepartment(node.children, code);
        if (found) return found;
      }
      return null;
    };

    return selectedDepartments
      .map(code => findDepartment(departments, code))
      .filter(Boolean) as DepartmentNode[];
  }, [departments, selectedDepartments]);

  // 도메인 할당 처리
  const handleDomainAssign = async (assignmentData: {
    departmentCodes: string[];
    domain: string;
    description?: string;
  }) => {
    // 선택된 부서들의 이름 매핑 생성
    const departmentNames: Record<string, string> = {};
    const collectDepartmentNames = (nodes: DepartmentNode[]) => {
      nodes.forEach(node => {
        if (assignmentData.departmentCodes.includes(node.departmentCode)) {
          departmentNames[node.departmentCode] = node.departmentName || node.departmentCode;
        }
        collectDepartmentNames(node.children);
      });
    };
    collectDepartmentNames(departments);

    startTransition(async () => {
      try {
        const result = await assignDomainToDepartments({
          departmentCodes: assignmentData.departmentCodes,
          domain: assignmentData.domain as UserDomain,
          description: assignmentData.description,
          departmentNames,
        });

        if (result.success) {
          toast.success(result.message);
          setSelectedDepartments([]);
          
          // 할당 정보 새로고침
          try {
            const updatedAssignments = await getDepartmentDomainAssignments();
            setAssignments(updatedAssignments as DepartmentAssignment[]);
          } catch (error) {
            console.error("할당 정보 새로고침 실패:", error);
          }
        } else {
          toast.error(result.message);
        }
      } catch (error) {
        console.error("도메인 할당 실패:", error);
        toast.error("도메인 할당 중 오류가 발생했습니다.");
      }
    });
  };

  const canAssign = selectedDepartments.length > 0;
  const selectedDepartmentInfo = getSelectedDepartmentInfo();

  const isLoading = isDepartmentsLoading || isAssignmentsLoading;

  return (
    <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
      {/* 왼쪽: 조직도 트리 */}
      <div className="lg:col-span-2">
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Settings className="h-5 w-5" />
              조직도 - {companyInfo.name}
            </CardTitle>
            <CardDescription>
              부서를 선택하여 도메인을 할당하세요. 상위 부서 선택 시 하위 부서들도 자동으로 포함됩니다.
            </CardDescription>
          </CardHeader>
          <CardContent className="p-0">
            {isLoading ? (
              <div className="flex items-center justify-center h-[80vh]">
                <div className="text-center">
                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
                  <p className="text-muted-foreground">조직도를 불러오는 중...</p>
                </div>
              </div>
            ) : (
              <DepartmentTreeView
                departments={departments}
                selectedDepartments={selectedDepartments}
                onSelectionChange={setSelectedDepartments}
                assignments={assignments}
              />
            )}
          </CardContent>
        </Card>
      </div>

      {/* 오른쪽: 선택된 부서 정보 및 할당 버튼 */}
      <div className="space-y-6">
        {/* 선택된 부서 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Users className="h-5 w-5" />
              선택된 부서
            </CardTitle>
            <CardDescription>
              {selectedDepartments.length}개 부서가 선택되었습니다
            </CardDescription>
          </CardHeader>
          <CardContent>
            {selectedDepartmentInfo.length === 0 ? (
              <div className="text-center py-4 text-muted-foreground">
                부서를 선택해주세요
              </div>
            ) : (
              <div className="space-y-2 max-h-60 overflow-y-auto">
                {selectedDepartmentInfo.map((dept) => {
                  const assignment = assignments.find(a => a.departmentCode === dept.departmentCode);
                  return (
                    <div
                      key={dept.departmentCode}
                      className="flex items-center justify-between p-2 bg-accent/20 rounded-md"
                    >
                      <div className="min-w-0">
                        <div className="font-medium truncate">
                          {dept.departmentName || dept.departmentCode}
                        </div>
                        <div className="text-xs text-muted-foreground">
                          {dept.departmentCode}
                        </div>
                      </div>
                      {assignment && (
                        <Badge variant="outline" className="text-xs shrink-0">
                          {assignment.assignedDomain}
                        </Badge>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </CardContent>
        </Card>

        {/* 도메인 할당 버튼 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">도메인 할당</CardTitle>
            <CardDescription>
              선택된 부서들에 도메인을 할당합니다
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Button
              onClick={() => setIsDialogOpen(true)}
              disabled={!canAssign || isPending}
              size="lg"
              className="w-full"
            >
              <Plus className="mr-2 h-4 w-4" />
              도메인 할당 ({selectedDepartments.length}개 부서)
            </Button>
            
            {canAssign && (
              <div className="mt-3 text-sm text-muted-foreground">
                상위 부서를 선택한 경우 하위 부서들도 자동으로 동일한 도메인이 할당됩니다.
              </div>
            )}
          </CardContent>
        </Card>

        {/* 범례 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">도메인 범례</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-1 gap-2 text-sm">
              {DOMAIN_OPTIONS.map((option) => (
                <div key={option.value} className="flex items-center gap-2">
                  <Badge className={option.color}>
                    {option.value}
                  </Badge>
                  <span>{option.description}</span>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      </div>

      {/* 도메인 할당 다이얼로그 */}
      <DepartmentDomainAssignmentDialog
        open={isDialogOpen}
        onOpenChange={setIsDialogOpen}
        selectedDepartments={selectedDepartments}
        departments={departments}
        companyInfo={companyInfo}
        onAssign={handleDomainAssign}
        isLoading={isPending}
      />
    </div>
  );
} 